#include "gatts.h"
#include "nvs_flash.h"

#include <stdio.h>
#include <stdbool.h>
#include <string.h>

#include "freertos/FreeRTOS.h"
#include "freertos/task.h"

#define uuid16(x)                               \
	{                                       \
		.bit_len = 16, .uuid.uuid16 = x \
	}

uint8_t nfc_conf[500] = "test conf";
uint8_t nfc_id[500] = "test id";
uint8_t nfc_data[500] = "test data";
uint8_t nfc_stat[500] = "test stat";

struct gatts_char chars[] = {
	// clang-format off
{.uuid = uuid16(0xFF01), .length = 20, .max_length = 500, .value = nfc_conf, .cccd = 0x0000, .perm = GATTS_PERM_READ|GATTS_PERM_WRITE|GATTS_PERM_NOTIFY|GATTS_PERM_INDICATE},
{.uuid = uuid16(0xFF02), .length = 16, .max_length = 500, .value = nfc_id, .cccd = 0x0000, .perm = GATTS_PERM_READ|GATTS_PERM_WRITE},
{.uuid = uuid16(0xFF03), .length = 16, .max_length = 500, .value = nfc_data, .cccd = 0x0000, .perm = GATTS_PERM_WRITE},
{.uuid = uuid16(0xFF04), .length = 16, .max_length = 500, .value = nfc_stat, .cccd = 0x0000, .perm = GATTS_PERM_NOTIFY|GATTS_PERM_INDICATE}
	// clang-format on
};

struct gatts_service service = { .uuid = uuid16(0x00FF),
				 .char_num = 4,
				 .characteristics = chars };

void read_callback(const struct gatts_uuid *uuid, uint8_t *send_data,
		   uint16_t *len);
void write_callback(const struct gatts_uuid *uuid, const uint8_t *recv_data,
		    uint16_t len);

struct gatts_profile profile[] = { { .dev_name = "esp_test",
				     .service_num = 1,
				     .services = &service,
				     .read_cb = read_callback,
				     .write_cb = write_callback } };

void read_callback(const struct gatts_uuid *uuid, uint8_t *send_data,
		   uint16_t *len)
{
	gatts_err_t ret;
	printf("read event\n");
	// 如果要修改发送的value值，使用以下方法
	// ret = gatts_set_value(uuid,value,len);

	ret = gatts_get_value(uuid, send_data, len, 600);

	return;
}

void write_callback(const struct gatts_uuid *uuid, const uint8_t *recv_data,
		    uint16_t len)
{
	gatts_err_t ret;
	printf("write event\n");
	ret = gatts_set_value(uuid, recv_data, len);

	// 如果要获取接收到的value值，使用以下方法
	// ret = gatts_get_value(uuid,value,len);

	return;
}

void app_main(void)
{
	esp_err_t ret;
	/* Initialize NVS. */
	ret = nvs_flash_init();
	if (ret == ESP_ERR_NVS_NO_FREE_PAGES ||
	    ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
		ESP_ERROR_CHECK(nvs_flash_erase());
		ret = nvs_flash_init();
	}
	ESP_ERROR_CHECK(ret);

	gatts_init(&profile[0]);
	vTaskDelay(10000 / portTICK_PERIOD_MS); // 100ms

	printf("notify\n");
	gatts_notify(&chars[0].uuid);
	vTaskDelay(3000 / portTICK_PERIOD_MS); // 100ms
	printf("notify\n");
	gatts_notify(&chars[3].uuid);
}
